home *** CD-ROM | disk | FTP | other *** search
/ MacFormat 1995 January / macformat-020.iso / Shareware City / Developers / apps.to.go / Kibitz / DoCursor.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-05-06  |  6.5 KB  |  251 lines  |  [TEXT/MPS ]

  1. /*
  2. ** Apple Macintosh Developer Technical Support
  3. **
  4. ** File:        docursor.c
  5. ** Written by:  Eric Soldan
  6. **
  7. ** Copyright © 1990-1992 Apple Computer, Inc.
  8. ** All rights reserved. */
  9.  
  10.  
  11.  
  12. /*****************************************************************************/
  13.  
  14.  
  15.  
  16. #include "Kibitz.h"                /* Get the Kibitz includes/typedefs, etc.    */
  17. #include "KibitzCommon.h"        /* Get the stuff in common with rez.        */
  18. #include "Kibitz.protos"        /* Get the prototypes for Kibitz.            */
  19.  
  20. #ifndef __OSEVENTS__
  21. #include <OSEvents.h>
  22. #endif
  23.  
  24. #ifndef __TEXTEDITCONTROL__
  25. #include <TextEditControl.h>
  26. #endif
  27.  
  28. #ifndef __TOOLUTILS__
  29. #include <ToolUtils.h>
  30. #endif
  31.  
  32. #ifndef __UTILITIES__
  33. #include <Utilities.h>
  34. #endif
  35.  
  36.  
  37.  
  38. /*****************************************************************************/
  39.  
  40.  
  41.  
  42. RgnHandle    gCurrentCursorRgn;
  43.     /* The current cursor region.  The initial cursor region is an empty
  44.     ** region, which will cause WaitNextEvent to generate a mouse-moved
  45.     ** event, which will cause us to set the cursor for the first time. */
  46.  
  47. Cursor    *gCurrentCursor, **gCurrentCursorHndl;
  48.     /* The current cursor that applies to gCurrentCursorRgn.  These values
  49.     ** are here to shorten the re-processing time for determining the
  50.     ** correct cursor after an event.  This is specifically so that characters
  51.     ** can be typed into the TextEdit control faster.  If we spend a great
  52.     ** deal of time per-event recalculating the cursor region, text entry for
  53.     ** the TextEdit control slows down considerably.  If you want to override
  54.     ** the time savings because you are changing the cursor directly, either
  55.     ** set gCurrentCursor to nil, or call DoSetCursor to set the cursor.
  56.     ** DoSetCursor simply sets gCurrentCursor to nil, as well as setting
  57.     ** the cursor. */
  58.  
  59.  
  60.  
  61. /*****************************************************************************/
  62. /*****************************************************************************/
  63.  
  64.  
  65.  
  66. /* Handle the cursor changes, based on if an AppleEvent is involved, or
  67. ** depending on the location of the cursor.  This also calculates the region
  68. ** where the current cursor resides (for WaitNextEvent).  If the mouse is
  69. ** ever outside of that region, an event would be generated, causing this
  70. ** function to be called, allowing us to change the region to the region
  71. ** the mouse is currently in.  The only other cursor management in this sample
  72. ** is for operations such as pulling down a menu.  Just prior to pulling down
  73. ** the menu, the arrow cursor is set.  This prevents any latencies in cursor
  74. ** update to cause a non-arrow cursor to be used in the menus.  This technique
  75. ** should be carried throughout the application. */
  76.  
  77. #pragma segment Main
  78. void    DoCursor(void)
  79. {
  80.     WindowPtr    window, oldPort;
  81.     WindowPeek    wpeek;
  82.     RgnHandle    rgn1, rgn2, rgn3;
  83.     Rect        boardRct, structRct, teViewRct;
  84.     Point        mouseLoc;
  85.     FileRecHndl    frHndl;
  86.     FileRecPtr    frPtr;
  87.     TEHandle    teHndl;
  88.     Boolean        readOnly, twoPlayer, canMove;
  89.     short        resync, myColor, moveColor;
  90.     EventRecord    option;
  91.  
  92.     mouseLoc = GetGlobalMouse();
  93.  
  94.     if ((!gInBackground) && (!IsDAWindow(window = FrontWindow()))) {
  95.  
  96.         if (IsAppWindow(window)) {
  97.  
  98.             if (gCurrentCursor) {
  99.                 if (PtInRgn(mouseLoc, gCurrentCursorRgn)) {
  100.                     SetCursor(*gCurrentCursorHndl);
  101.                     return;
  102.                 }
  103.             }
  104.  
  105.             SetEmptyRgn(gCurrentCursorRgn);
  106.             GetPort(&oldPort);
  107.  
  108.             if (CTETargetInfo(&teHndl, &teViewRct) == window) {
  109.                 SetPort(window);
  110.                 SectRect(&teViewRct, &(window->portRect), &teViewRct);
  111.                 LocalToGlobalRect(&teViewRct);
  112.                 SetPort(oldPort);
  113.                 RectRgn(gCurrentCursorRgn, &teViewRct);
  114.                 if (PtInRect(mouseLoc, &teViewRct)) {
  115.                     SetCursor(gCurrentCursor = *(gCurrentCursorHndl = GetCursor(ibeamCursor)));
  116.                     return;
  117.                 }
  118.             }
  119.  
  120.             rgn1 = NewRgn();
  121.             rgn2 = NewRgn();
  122.             rgn3 = NewRgn();
  123.  
  124.             wpeek = (WindowPeek)window;
  125.             for (; wpeek; wpeek = wpeek->nextWindow) {
  126.  
  127.                 if (IsAppWindow((WindowPtr)wpeek)) {
  128.  
  129.                     frHndl = (FileRecHndl)GetWRefCon((WindowPtr)wpeek);
  130.                     frPtr  = *frHndl;
  131.                     readOnly  = frPtr->fileState.readOnly;
  132.                     twoPlayer = frPtr->doc.twoPlayer;
  133.                     resync    = frPtr->doc.resync;
  134.                     myColor   = frPtr->doc.myColor;
  135.                     moveColor = WhosMove(frHndl);
  136.  
  137.                     OSEventAvail(nullEvent, &option);
  138.                     if (option.modifiers & optionKey)
  139.                         if (myColor != kMessageDoc) myColor = moveColor;
  140.  
  141.                     canMove = true;
  142.  
  143.                     if (readOnly)
  144.                         canMove = false;
  145.                     if ((twoPlayer) && (myColor != moveColor))
  146.                         canMove = false;
  147.                     if (myColor == kMessageDoc)
  148.                         canMove = false;
  149.                     if (GameStatus(frHndl) != kGameContinues)
  150.                         canMove = false;
  151.                     if ((moveColor == WHITE) && ((*frHndl)->doc.compMovesWhite))
  152.                         canMove = false;
  153.                     if ((moveColor == BLACK) && ((*frHndl)->doc.compMovesBlack))
  154.                         canMove = false;
  155.                     if ((resync == kScrolling) || (resync == kResync))
  156.                         canMove = false;
  157.  
  158.                     if (canMove) {
  159.                         boardRct = GlobalBoardRect((WindowPtr)wpeek);
  160.                         RectRgn(rgn1, &boardRct);
  161.                         DiffRgn(rgn1, rgn2, rgn1);
  162.                         UnionRgn(rgn3, rgn1, rgn3);
  163.                     }
  164.                 }
  165.  
  166.                 structRct = GetWindowStructureRect((WindowPtr)wpeek);
  167.                 RectRgn(rgn1, &structRct);
  168.                 UnionRgn(rgn1, rgn2, rgn2);
  169.             }        /* Assume cursor is over an app content. */
  170.  
  171.             if (!PtInRgn(mouseLoc, rgn3)) {
  172.                     /* The cursor wasn't over a chessboard after all. */
  173.                 SetRectRgn(rgn1, kExtremeNeg, kExtremeNeg,
  174.                                  kExtremePos, kExtremePos);
  175.                 DiffRgn(rgn1, rgn3, rgn3);
  176.                 gCurrentCursor     = &qd.arrow;
  177.                 gCurrentCursorHndl = &gCurrentCursor;
  178.                 SetCursor(gCurrentCursor);
  179.             }
  180.             else SetCursor(*(gCurrentCursorHndl = GetCursor(handCursor)));
  181.  
  182.             DiffRgn(rgn3, gCurrentCursorRgn, gCurrentCursorRgn);
  183.  
  184.             DisposeRgn(rgn1);
  185.             DisposeRgn(rgn2);
  186.             DisposeRgn(rgn3);
  187.             return;
  188.         }
  189.  
  190.         else DoSetCursor(&qd.arrow);
  191.     }
  192.  
  193.     else {
  194.         SetRectRgn(gCurrentCursorRgn, kExtremeNeg, kExtremeNeg,
  195.                                       kExtremePos, kExtremePos);
  196.         gCurrentCursor = nil;
  197.     }
  198. }
  199.  
  200.  
  201.  
  202. /*****************************************************************************/
  203.  
  204.  
  205.  
  206. #pragma segment Main
  207. void    DoSetCursor(Cursor *cursor)
  208. {
  209.     if (cursor) SetCursor(cursor);
  210.     gCurrentCursor = nil;
  211.     if (!cursor) DoCursor();
  212. }
  213.  
  214.  
  215.  
  216. /*****************************************************************************/
  217.  
  218.  
  219.  
  220. #pragma segment Main
  221. Rect    BoardRect(void)
  222. {
  223.     Rect    boardRct;
  224.  
  225.     SetRect(&boardRct, kBoardHOffset + 1, kBoardVOffset + 1,
  226.              kBoardHOffset + 8 * kBoardSqSize + 1,
  227.              kBoardVOffset + 8 * kBoardSqSize + 1);
  228.     return(boardRct);
  229. }
  230.  
  231.  
  232.  
  233. /*****************************************************************************/
  234.  
  235.  
  236.  
  237. #pragma segment Main
  238. Rect    GlobalBoardRect(WindowPtr window)
  239. {
  240.     Rect    boardRct, windRct;
  241.  
  242.     boardRct = BoardRect();
  243.     windRct  = GetWindowContentRect(window);
  244.  
  245.     OffsetRect(&boardRct, windRct.left, windRct.top);
  246.     return(boardRct);
  247. }
  248.  
  249.  
  250.  
  251.